#include "stdafx.h"

#ifndef _SECURIT_H
#define _SECURIT_H

#include <modes.h> // xxx_Mode< >
#include <osrng.h>   // AutoSeededRandomPool
#include <dh.h>  // dh
#include <hex.h>
#include <filters.h>
#include <aes.h>


typedef unsigned char uint8_t; 
typedef unsigned short uint16_t; 


using namespace std;
using namespace CryptoPP;

/*! \def DH_PRIME                                                                                  
 numero primo fisso a 4096 bit secondo lo standard                                                                        
 */
#define DH_PRIME "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF"
/*! \def DH_GENERATOR                                                                                  
 numero generatore secondo lo standard                                                                        
 */
#define DH_GENERATOR "0x02" 

/*
 dimensione in byte delle chiavi DH                                                                           
 */
#define DH_SIZE 512 
/*! \def SHA_SIZE                                                                                  
 dimensione in byte delle chiavi SHA                                                                           
 */
#define SHA_SIZE 32
#define ARRAYKEYSIZE 1024 
/*! \def HMACSTREAMTX                                                                                  
 firma HMAC per derivare la chiave da passare in ingresso al blocco XOR per la cifratura AES-CTR MODE, lato TX                                                                          
 */
#define HMACSTREAM_IN "hmac stream initiator"
/*! \def HMACSTREAMRX                                                                                  
 firma HMAC per derivare la chiave da passare in ingresso al blocco XOR per la cifratura AES-CTR MODE, lato RX                                                                          
 */
#define HMACSTREAM_RE "hmac stream responder"
/*! \def HMACVECTTX                                                                                  
 firma HMAC per derivare la chiave da passare in ingresso al vettore di inizializzazione per la cifratura AES-CTR MODE, lato TX                                                                          
 */
#define HMACVECT_IN "hmac vect initiator"
/*! \def HMACVECTRX                                                                                  
 firma HMAC per derivare la chiave da passare in ingresso al vettore di inizializzazione per la cifratura AES-CTR MODE, lato RX                                                                          
 */
#define HMACVECT_RE "hmac vect responder"
/*! \def HMACCONV                                                                                  
 firma HMAC per derivare la chiave necessaria per ottenere la stringa vocale                                                                         
 */
#define HMACCONV "hmac conv for SAS"

class Security
{

private: 
Integer iPrime;
Integer iGenerator;
SecByteBlock pub;
SecByteBlock pubEP;
SecByteBlock priv;
SecByteBlock secretkey;
SecByteBlock SHAkey;
SecByteBlock HMACvect_TX;
SecByteBlock HMACvect_RX;
SecByteBlock HMACstream_TX;
SecByteBlock HMACstream_RX;
SecByteBlock HMACconv;
string voicekey;
string plaintext;
string chipertext;
string recoveredtext;
char counter[32];
CryptoPP::CTR_Mode< CryptoPP::AES >::Encryption Encryptor;
CryptoPP::CTR_Mode< CryptoPP::AES >::Decryption Decryptor;
DH dh;

public:
	Security(void);
	//!Costruttore di copia
	/*!
	Inizializza il costruttore di copia dell'oggetto.
	*/
	Security(const Security &);
	~Security(void);
	//!Generatore chiavi in trasmissione DH
	/*!
	Genera la chiavi in trasmissione a 4096 bit publliche e private secondo l'algoritmo Diffie - Hellmann.
	*/
	void dhSender();
	//!Generatore chiavi in ricezione DH
	/*!
	Genera la chiavi in ricezione a 4096 bit publliche e private secondo l'algoritmo Diffie - Hellmann e il numero primo e Generatore passato da 
	chi inizia la trasmissione, questi numeri sono hardcoded.
	*/
	void dhReceiver(Integer,Integer);
	//!Generatore SHA-256 del segreto condiviso
	/*!
	Effettua lo SHA-256 della chiave segreta condivisa ricavata tra i due interlocutori.
	*/
	SecByteBlock generaSHAkey(SecByteBlock);
	//!Generatore HMAC di una chiave
	/*!
	Genera l'HMAC di una chiave prendendo in input la chiave, la sua lunghezza, e una stringa appropriata .
	*/
	SecByteBlock generaHMACkey(SecByteBlock,int,string);
	
	//!Generatore buffer counter
	/*!
	Ritorna un buffer che contiene il 240 bit dell'HMAC della chiave SHA a 256 bit e negli ultimi 16 bit un intero a 16 bit che viene
	utilizzato come contatore nella cifrature AES-CTR mode. 
	*/
	char* calculatecounter(SecByteBlock, int,uint16_t);
	
	//!Unione tra la key e il counter
	/*!
	Unisce il buffer counter con la chiave desiderata, in fase di criptazione.
	*/
	CryptoPP::CTR_Mode< CryptoPP::AES >::Encryption calculatekeystream(char *,SecByteBlock);
	Integer getiPrime();
	Integer getiGenerator();
	SecByteBlock getpub();
	SecByteBlock getpubEP();
	SecByteBlock getpriv();
	SecByteBlock getsecretkey();
	SecByteBlock getSHAkey();
	SecByteBlock getHMACvect_TX();
	SecByteBlock getHMACvect_RX();
	SecByteBlock getHMACstream_TX();
	SecByteBlock getHMACstream_RX();
	SecByteBlock getHMACconv();
	string getvoicekey();
	void setvoicekey(string);
	void setplaintext(string);
	string getplaintext();
	string getchipertext();
	void setchipertext(string);
	string getrecoveredtext();
	void setrecoveredtext(string);
	void setSHAkey(SecByteBlock);
	void setHMACvect_TX(SecByteBlock);
	void setHMACvect_RX(SecByteBlock);
	void setHMACstream_TX(SecByteBlock);
	void setHMACstream_RX(SecByteBlock);
	void setHMACconv(SecByteBlock);
	void setpubEP(SecByteBlock);
	DH getdh();
	//!Generatore chiave segreta condivisa DH
	/*!
	Calcola la chiave segreta condivisa di DH dato l'altro interlocutore.
	*/
	bool calcolasecretkey(SecByteBlock);
	
	//!Cast SecByteBlock-string
	/*!
	Effettua una conversione tra l'oggetto SecByteBlock a string . Prende in ingresso la chiave desiderata e la sua lunghezza,
	restituisce una stringa.
	*/
	string convertkeytostring(SecByteBlock,int);
	//!Lookuptable per ricavare stringa vocale
	/*!
	Questa lookuptable permette di convertire un carattere ascii in un altro carattere , utilizzata nel calcolo della stringa vocale.
	*/
	char lookuptable(uint8_t);
	//!Generazione Stringa Vocale
	/*!
	Permette di ricavare la stringa vocale, prende in input la chiave desiderata e la sua lunghezza.
	*/
	string convertkeytoshortstring(SecByteBlock,int);
	char* getcounter();
	void setcounter(char*);

	CryptoPP::CTR_Mode< CryptoPP::AES >::Encryption getEncryptor();
    void setEncryptor(CTR_Mode< CryptoPP::AES >::Encryption);
	CryptoPP::CTR_Mode< CryptoPP::AES >::Decryption getDecryptor();
    void setDecryptor(CTR_Mode< CryptoPP::AES >::Decryption);
	//!Unione tra la key e il counter
	/*!
	Unisce il buffer counter con la chiave desiderata, in fase di decriptazione.
	*/
	CryptoPP::CTR_Mode< CryptoPP::AES >::Decryption decryptkeystream(char *,SecByteBlock);
	//!Funzione di cifratura
	/*!
	Effettua la cifratura di un testo in chiaro , secondo l'algoritmo AES-CTR MODE
	*/
	string plaintextxorblockchiper(string,CTR_Mode< CryptoPP::AES >::Encryption);
	//!Funzione di decifratura
	/*!
	Effettua la decifratura di un testo cifrato , secondo l'algoritmo AES-CTR MODE
	*/
	string chipertextxorblockchiper(string,CTR_Mode< CryptoPP::AES >::Decryption);
};


#endif
